#ifndef CTETRA_H
#define CTETRA_H

/*
Last edited 12/24/2010 by Marco A. Moreno aka S.T.B. aka Jake Prophet
This file is part of the MarCore game engine. The MarCore game engine is a
thin core and wrapper that binds several other libraries.
*/
/*
Class CTetra is specific to solids as of now.
Liquids will be handled later once a more 'solid' concept is
hammered out.
*/

#include <irrlicht.h>
#include "IGameObject.h"
#include "CTetraVertex.h"
#include "CTetraManager.h"
#include "CTetraBuffer.h"
#include "ISceneNode.h"

//#include "BulletCollision/Gimpact/btGImpactShape.h"

/*
#include "btBulletCollisionCommon.h"
#include "btBulletDynamicsCommon.h"
*/

namespace MarCore
{

namespace Tetra
{

class CTetraBuffer;

// Update flag for tetra mesh, updates physics collision shape and/or irrlicht graphics mesh.
enum E_UPDATE_TETRA_MESH
{

    E_BOTH,

    E_GRAPHICS,

    E_PHYSICS,

    E_COUNT

};

class CTetra : public IGameObject
{

    //! Official IGameObject register deriviation id number.
    int goid;

    CTetraVertex* vertices;

    ///!
    //btTetrahedronShapeEx* collision_shape;

    f32 mass; //total mass of the CTetraVertex objs

    f32 strength; //total strength of each face

    ///@todo This should be entirely handled by the btRigidBody
    //btTetrahedronShapeEx* collision_shape; //the bullets collision shape
    //@todo modify plans to hold pointer to entirely encapuslated bullet body

    /// Tetra manager pointer
    CTetraManager* manager;

    CTetraBuffer* buffer; //pointer to its parent buffer

    u32 buffer_index; //this index in the buffer.

    bool active; //active for simulation? Simple yes or no, optimizes performance

    bool needsUpdate; //update flag

public:

    //! Default constructor
    CTetra();

    ///@note Is the mngr arg really needed? Couldn't the mngr use this call DIRECTLY?
    /// THEN let the CTetra create itself and its physics and graphics objects?
    //! Constructor
    CTetra( CTetraVertex* vertices_, CTetraManager* mngr_, IGameObject* rod__, CGameObjectArray* crank__);

    //! Destructor
    ~CTetra();

    //! Updates the irrlicht and/or bullet vertices.
    void updateMesh(E_UPDATE_TETRA_MESH update);

    //! Updates irrlicht graphics mesh.
    void updateGraphicsMesh();

    //! Updates bullets collision mesh.
    void updatePhysicsMesh();

    //! Set the needsUpdate flag
    void setNeedsUpdate( bool update );

    // Draws itself using irrlicht.
    ///@todo Take this out, all optimizations should be handled at
    /// the level lower than this with irrlicht and other custom things
    // void draw();

    ///@note As of now, we are aiming for one single material. However, I want realtime shadows on EVERYTHING. :)
    /// hence only setTexture(), there is no setMaterial, there is only one material and it is defined internally
    /// and automatically.

    ///@todo This is only to test and get familiar with irrlicht integration. We are aiming to have each vertex define
    /// its own texture, and have texture gradiance on each face. Low priority
    //! Sets the texture.
    void setTexture();

    //! Returns pointer to vertices.
    CTetraVertex* getVertices();

/*
    //! Returns pointer to Irr derived node
    scene::ISceneNode* getIrrNode();
*/

    //! Returns tetra buffer index.
    const u32 getBufferIndex();

    //! Recalculates mass of the Tetra
    void updateMass();

    //! Adds a force area that collided with one of this' faces to the register for solving later with stroke() method
    void addCollidedForce( core::vector3df& poc/*point of contact*/, core::vector3df& end );
/*
    //! Sets the parent 'rod'
    void setRod( IGameObject* new_rod );

    //! Adds a child 'crank'
    void addCrank( const IGameObject& new_crank );

    //! Run a tick amount.
    void stroke();
*/

};  //end class CTetra



}; //end namespace Tetra
}; //end namespace MarCore

#endif //CTETRA_H
